# -*- coding: utf-8 -*-
import re,logging,os
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.api import memcache
from getimageinfo import getImageInfo
loglog = True

BUCKET_NAME = "gs.itiens.com" #填写你已经存在的 BUCKET NAME
GS_ACCESS_KEY_ID = "GOOGBW74FPBDSBJCC7FI" #填写你自己的 GS_ACCESS_KEY_ID
GS_SECRET_ACCESS_KEY = "tjIkseLVCLuMVZCKKRj2q+2mH+93ahaUImf9Adpw" #填写你自己的 GS_SECRET_ACCESS_KEY

import boto
config = boto.config
try:
    config.add_section('Credentials')
except:pass
config.set('Credentials', 'gs_access_key_id', GS_ACCESS_KEY_ID)
config.set('Credentials', 'gs_secret_access_key', GS_SECRET_ACCESS_KEY)

def upload2gs(bucket, filename, content, folder=None, mime_type=None, is_public=True):
    if folder:
        filename = "%s/%s"%(folder,filename)
    bucket_uri = boto.storage_uri(bucket, 'gs')
    object_uri = bucket_uri.clone_replace_name(filename)
    object_key = object_uri.new_key()

    headers = {}
    if mime_type:
        headers['Content-Type'] = mime_type
    if is_public:
        headers['x-goog-acl'] = 'public-read'
    object_key.set_contents_from_string(content, headers)
    if is_public:
        if '.' in bucket:
            template = 'http://%s/%s'
        else:
            template = 'https://%s.commondatastorage.googleapis.com/%s'
            #template = 'https://commondatastorage.googleapis.com/%s/%s'
    else:
        template = 'https://sandbox.google.com/storage/%s/%s'

    return template % (bucket, filename)

class sysres(db.Model):
    restype = db.StringProperty(required=True)
    name = db.StringProperty(required=True)
    refmod = db.StringProperty(required=True)

class sysforms(db.Model):
    refapp = db.StringProperty(required=True)
    formid = db.StringProperty(required=True)
    actionurl = db.StringProperty(required=True)
    styleclass = db.StringProperty(required=True)
    formtitle = db.StringProperty(required=True)
    enctype = db.StringProperty(required=True, choices=set(['application/x-www-form-urlencoded','multipart/form-data']), default='application/x-www-form-urlencoded')
    formethod = db.StringProperty(required=True, choices=set(['post','get']), default='post')

class role(db.Model):
    name = db.StringProperty(required=True)#administrator > master > manager >stuff
    tpurl = db.StringProperty(required=True)

class admin(db.Model):
    isadmin = db.BooleanProperty(required=True, default=False)
    email = db.EmailProperty(required=True)
    name = db.StringProperty(required=True)
    role = db.ReferenceProperty(role, collection_name="roleaccount", required=True)
    refcstore = db.ReferenceProperty(collection_name="staff", required=True)#所属店/公司

class cstore(db.Model):
    regref = db.SelfReferenceProperty(collection_name="branch") #所属公司key
    type = db.StringProperty(required=True, choices=set(['aa','ab', 'ca', 'cb']), default='aa') #公司类型
    code = db.StringProperty(required=True)
    name = db.StringProperty(required=True)
    owner = db.ReferenceProperty(admin, collection_name="ownstore") #负责人
    addr = db.PostalAddressProperty()
    postcode = db.StringProperty()
    phone = db.StringProperty(default='')
    mobile = db.StringProperty(default='')
    refpo = db.SelfReferenceProperty(collection_name="postore") #默认的进货公司/店
    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class pvtype(db.Model):
    code = db.StringProperty(required=True)
    name = db.StringProperty(required=True)
    ratepv = db.RatingProperty(required=True, default=85)
    pvrate = db.RatingProperty(required=True)
    bvrate = db.RatingProperty(required=True)
    locked = db.BooleanProperty(required=True, default=False)
    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class prodcls(db.Model):
    refcls = db.SelfReferenceProperty(collection_name="subcls") #所属分类
    code = db.StringProperty(required=True)
    name = db.StringProperty(required=True)
    csstyle = db.StringProperty()
    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class prodpic(db.Model):
    ref = db.StringProperty() #prod.code
    mime = db.StringProperty()
    size = db.IntegerProperty()
    filetype = db.StringProperty()
    width = db.IntegerProperty()
    height = db.IntegerProperty()
    name = db.StringProperty() #文件名
    title = db.StringProperty() #描述，prod.name
    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

    fbin = db.BlobProperty() #binary file

    @classmethod
    def add(cls, ref, name, mime, title, fbin):
        pic = prodpic(ref=ref, name=name, mime=mime, title=title, fbin=fbin)
        pic.size = len(pic.fbin)
        pic.filetype, pic.width, pic.height = getImageInfo(fbin)
        pic.put()
        memcache.set("prodpic"+ str(pic.key().id()), pic, 864000)
        if loglog:
            logging.debug("Admin_Log:addnew prodpic(key:%s) detail(ref:%s,name:%s,mime:%s,title:%s,width:%s,height:%s,size:%s,filetype:%s) by %s" %
            (pic.key(), pic.ref, pic.name, pic.mime, pic.title, pic.width, pic.height, pic.size, pic.filetype, users.get_current_user().email()))
        return pic

    def remove(self):
        memcache.delete("prodpic"+ str(self.key().id()))
        self.delete()
        if loglog:
            logging.warning("Admin_Log:delete prodpic(key:%s) detail(ref:%s,name:%s,mime:%s,title:%s,width:%s,height:%s,size:%s,filetype:%s) by %s" %
            (self.key(), self.ref, self.name, self.mime, self.title, self.width, self.height, self.size, self.filetype, users.get_current_user().email()))

    @property
    def id(self):
        return self.key().id()

    @property
    def src(self):
        return "/pp/%s" % ( self.key().id() )
    @property
    def url(self):
        return "http://%s/pp/%s" % (os.environ['HTTP_HOST'], self.key().id())

class prod(db.Model):
    code = db.StringProperty(required=True)
    name = db.StringProperty(required=True)
    spec = db.StringProperty(required=True)
    unit = db.StringProperty(required=True)
    pvtype = db.ReferenceProperty(pvtype, required=True, collection_name="pvprod")
    refcls = db.ReferenceProperty(prodcls, collection_name="clsprod")
    price = db.FloatProperty(required=True)
    picid = db.IntegerProperty()
    picurl = db.StringProperty()
    status = db.StringProperty(required=True, choices=set(['active', 'locked', 'soldout', 'exitmarket']), default='active') #产品状态：正常，锁定，断货，退市
    sepreport = db.BooleanProperty(default=False)

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

    def remove(self):
        if self.picid:
            pp = prodpic.get_by_id(self.picid)
            if pp:
                pp.remove()
        self.delete()

class vip(db.Model):
    refcmpny = db.ReferenceProperty(cstore, collection_name="companyvip")
    refstore = db.ReferenceProperty(cstore, collection_name="storevip")
    refvip = db.SelfReferenceProperty(collection_name="subvip")
    apldate = db.DateProperty()
    idcard = db.StringProperty(required=True)
    vipname = db.StringProperty(required=True)
    gender = db.BooleanProperty()
    phone = db.StringProperty(default='')
    mobile = db.StringProperty(default='')
    vipcard = db.StringProperty(default='')
    vipcardsn = db.StringProperty(default='')

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class stock(db.Model):
    refcstore = db.ReferenceProperty(cstore, collection_name="storestock", required=True)
    prod = db.ReferenceProperty(prod, collection_name="prodstock", required=True)
    prodcode = db.StringProperty(required=True)
    pvtype = db.ReferenceProperty(pvtype, required=True, collection_name="pvtypestock")
    qty = db.IntegerProperty(required=True)

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class pvstock(db.Model):
    refcstore = db.ReferenceProperty(cstore, collection_name="storepvstock", required=True)
    pvstocktype = db.StringProperty(default='purchase', choices=set(['oldbalance', 'purchase', 'pvreport', 'balance', 'locked']))
    pvterm = db.DateProperty(required=True, auto_now_add=True)
    pvtype = db.ReferenceProperty(pvtype, required=True, collection_name="pvspvt")
    pvcode = db.StringProperty()
    amount = db.FloatProperty(required=True, default=0.0)
    pv = db.FloatProperty()
    bv = db.FloatProperty()

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class purorder(db.Model):
    orderno = db.StringProperty(required=True)
    refcstore = db.ReferenceProperty(cstore, collection_name="storepo", required=True)
    popv = db.FloatProperty(default=0.0)
    pobv = db.FloatProperty(default=0.0)
    qty = db.IntegerProperty(required=True, default=0)
    amount = db.FloatProperty()
    orderdate = db.DateTimeProperty()
    senddate = db.DateTimeProperty()
    finishdate = db.DateTimeProperty()
    status = db.StringProperty(required=True, choices=set(['editing', 'ordering', 'sending', 'success', 'locked']), default='editing') #订单状态：编辑，发出订货中，发货，完成，锁定

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class purorderprod(db.Model):
    orderno = db.ReferenceProperty(purorder, collection_name="polist", required=True)
    prod = db.ReferenceProperty(prod, collection_name="poprod", required=True)
    prodcode = db.StringProperty(required=True)
    prodname = db.StringProperty(required=True)
    unit = db.StringProperty(required=True)
    price = db.FloatProperty(required=True)
    qty = db.IntegerProperty(required=True)
    amount = db.FloatProperty()
    pv = db.FloatProperty()
    bv = db.FloatProperty()

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

class pvreport(db.Model):
    date = db.DateProperty(required=True, auto_now_add=True)
    refcstore = db.ReferenceProperty(cstore, required=True)
    pvterm = db.DateProperty(required=True, auto_now_add=True)
    qty = db.IntegerProperty(required=True)
    amount = db.FloatProperty()
    pv = db.FloatProperty()
    bv = db.FloatProperty()
    status = db.StringProperty(choices=set(['editing', 'sending', 'success', 'locked']), default='editing')
    locked = db.BooleanProperty(default=False)

class salesbill(db.Model):
    date = db.DateProperty(required=True, auto_now_add=True)
    refcstore = db.ReferenceProperty(cstore, collection_name="salesbills", required=True)
    vip = db.ReferenceProperty(vip, collection_name="salesbills", required=True)
    vipname = db.StringProperty()
    vipid = db.StringProperty()
    qty = db.IntegerProperty(required=True)
    amount = db.FloatProperty()
    locked = db.BooleanProperty(default=False)

class sales(db.Model):
    refsalesbill = db.ReferenceProperty(salesbill, required=True)
    refcstore = db.ReferenceProperty(cstore, required=True)
    vip = db.ReferenceProperty(vip, required=True)
    vipname = db.StringProperty()
    vipid = db.StringProperty()
    date = db.DateProperty(required=True, auto_now_add=True)
    prod = db.ReferenceProperty(prod, required=True)
    prodcode = db.StringProperty()
    prodname = db.StringProperty()
    pvtypename = db.StringProperty()
    unit = db.StringProperty()
    price = db.FloatProperty(required=True)
    qty = db.IntegerProperty(required=True)
    amount = db.FloatProperty()
    pv = db.FloatProperty()
    bv = db.FloatProperty()

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

    def remove(self):
        cs = self.refcstore
        prod = self.prod
        pvt = prod.pvtype
        septag = prod.code if prod.sepreport else ''
        vip = self.vip
        pvtpv = vip.vippvsales.filter('refcstore =', cs).filter('pvtype =', pvt).filter('septag =', septag).get()
        if pvtpv:
            if pvtpv.amount>=self.amount:
                pvtpv.pv -= round(self.pv, 5)
                pvtpv.bv -= round(self.bv, 5)
                pvtpv.amount -= round(self.amount, 5)
                pvtpv.put()
                self.delete()
                if loglog:
                    logging.debug("Admin_Log:modify- vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,idcard:%s,pvtype:%s|%s|%s,pv:%s,bv:%s,amount:%s) by %s" %
                    (pvtpv.key(), cs.key(), cs.code, cs.name, vip.key(), vip.lastname+vip.firstname, vip.idcard, vip.idcard, pvt.key(), pvt.code, pvt.name, self.pv, self.bv, self.amount, users.get_current_user().email()))
                return True
            else:
                return False
        else:
            return False

class vipvsales(db.Model):
    refcstore = db.ReferenceProperty(cstore, collection_name="storevipvsales", required=True)
    vip = db.ReferenceProperty(vip, collection_name="vippvsales", required=True)
    idcard = db.StringProperty(required=True)
    pvtype = db.ReferenceProperty(pvtype, required=True, collection_name="vipvspvt")
    pv = db.FloatProperty(required=True, default=0.0)
    bv = db.FloatProperty(required=True, default=0.0)
    amount = db.FloatProperty(required=True, default=0.0)
    septag = db.StringProperty(default='')

    cre8time = db.DateTimeProperty(auto_now_add=True)
    cre8user = db.UserProperty(auto_current_user_add=True)
    lmtime = db.DateTimeProperty(auto_now=True)
    lmuser = db.UserProperty(auto_current_user=True)

    @classmethod
    def addnew(cls, refstore, vip, pvtype, pv, bv, amount, septag=''):
        vpv = vipvsales(refcstore=refstore, vip=vip, idcard=vip.idcard, pvtype=pvtype, pv=pv, bv=bv, amount=amount, septag=septag)
        vpv.put()
        if loglog:
            logging.debug("Admin_Log:addnew vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,idcard:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
            ( vpv.key(), refstore.key(), refstore.code, refstore.name, vip.key(), vip.lastname+vip.firstname, vip.idcard, pvtype.key(), pvtype.code, pv, bv, amount, septag, users.get_current_user().email()))

    @classmethod
    def modify1(cls, refstore, vip, pvtype, pv, bv, amount, septag=''):
        vpv = refstore.storevipvsales.filter('vip =', vip).filter('pvtype =', pvtype).filter('septag =', septag).get()
        if vpv:
            vpv.pv = round(vpv.pv+pv, 5)
            vpv.bv = round(vpv.bv+bv, 5)
            vpv.amount = round(vpv.amount+amount, 5)
            vpv.put()
            if loglog:
                logging.debug("Admin_Log:modify+ vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,idcard:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
                ( vpv.key(), refstore.key(), refstore.code, refstore.name, vip.key(), vip.lastname+vip.firstname, vip.idcard, pvtype.key(), pvtype.code, pv, bv, amount, septag, users.get_current_user().email()))
        else:
            cls.addnew(refstore, vip, pvtype, pv, bv, amount, septag)

    @classmethod
    def modify(cls, refstore, vip, pvtype, pv, bv, amount, septag='', orisale=None):
        if orisale:
            orics = orisale.refcstore
            oripvt = orisale.prod.pvtype
            orivip = orisale.vip
            orisep = orisale.prodcode if orisale.prod.sepreport else ''
            orivpv = orics.storevipvsales.filter('vip =', orivip).filter('pvtype =', oripvt).filter('septag =', orisep).get()
            if orivpv:
                if orivip.key() == vip.key():
                    if oripvt.key() == pvtype.key():
                        if orivpv.amount<(orisale.amount-amount):
                            return False, 2
                        elif orisep==septag:
                            orivpv.pv = round(orivpv.pv-orisale.pv+pv, 5)
                            orivpv.bv = round(orivpv.bv-orisale.bv+bv, 5)
                            orivpv.amount = round(orivpv.amount-orisale.amount+amount, 5)
                            orivpv.put()
                            if loglog:
                                logging.debug("Admin_Log:modify vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,idcard:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
                                (orivpv.key(), refstore.key(), refstore.code, refstore.name, orivip.key(), orivip.lastname+orivip.firstname, orivip.idcard, orivip.idcard, pvtype.key(), pvtype.code, (orisale.pv-pv), (orisale.bv-bv), (orisale.amount-amount), septag, users.get_current_user().email()))
                            return True, 0
                    elif orivpv.pv<orisale.pv:
                        return False, 3
                elif orivpv.pv<orisale.pv:
                    return False, 4
            else:
                return False, 1
            orivpv.pv = round(orivpv.pv-orisale.pv, 5)
            orivpv.bv = round(orivpv.bv-orisale.bv, 5)
            orivpv.amount = round(orivpv.amount-orisale.amount, 5)
            orivpv.put()
            if loglog:
                logging.debug("Admin_Log:modify- vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,idcard:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
                (orivpv.key(), refstore.key(), refstore.code, refstore.name, orivip.key(), orivip.lastname+orivip.firstname, orivip.idcard, orivip.idcard, pvtype.key(), pvtype.code, (orisale.pv-pv), (orisale.bv-bv), (orisale.amount-amount), septag, users.get_current_user().email()))
        cls.modify1( refstore, vip, pvtype, pv, bv, amount, septag )
        return True, 0

class vipv(db.Model):
    vip = db.ReferenceProperty(vip, required=True)
    idcard = db.StringProperty(required=True)
    selfpv = db.FloatProperty(required=True)
